// define the namespaces
jmaki.namespace("jmaki.widgets.yahoo.grid");

/**
 * Yahoo UI Grid Widget
 *
 * @author Greg Murray
 *      original author
 * @author Ahmad M. Zawawi <ahmad.zawawi@gmail.com>
 *      Updated the widget to use glue publish/subscribe and added proper events
 *
 * @see http://developer.yahoo.com/yui/datatable/
 */
jmaki.widgets.yahoo.grid.Widget = function(wargs) {
    
    var topic = "/yahoo/grid";
    var uuid = wargs.uuid;
    var container = document.getElementById(uuid);
    var filter = "jmaki.filters.tableFilter";
    var self = this;
    var _model;
    var cm;
    
    var data;
    // yahoo normalized data
    var nData =[];
    var cols = [];
    var cold;
    var rowSingleSelect = true;
    
    //read the widget configuration arguments
    if (typeof wargs.args != 'undefined') {
        //overide topic name if needed
        if (typeof wargs.args.topic != 'undefined') {
            topic = wargs.args.topic;
        }  
        
        //grid columns
        if (typeof wargs.args.columns != 'undefined') {
            cold =   wargs.args.columns;
        }
        //grid filter
        if (typeof wargs.args.filter != 'undefined') { 
            filter = wargs.args.filter;
        }
        //row single selection flag
        if(typeof wargs.args.rowSingleSelect != 'undefined') { 
            rowSingleSelect = wargs.args.rowSingleSelect;
        }
    }
    
    var schema = [];
    
    
    if (wargs.value) {
        // convert value if a jmakiRSS type
        if (wargs.value.dataType == 'jmakiRSS') {
            wargs.value = jmaki.filter(wargs.value, filter);
        }
        data = wargs.value;
        init();
    } else if (wargs.service) {
        jmaki.doAjax({url: wargs.service, callback: function(req) {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    var _in = eval('(' + req.responseText + ')');
                    // convert value if a jmakiRSS type
                    if (_in.dataType == 'jmakiRSS') {
                        _in = jmaki.filter(_in, filter);
                    }
                    if (_in.rows) {
                        data = _in.rows;
                    }  else {
                        data = _in;
                    }
                    if (!cold && _in.columns) {
                        cold = _in.columns;
                    }
                    init();
                }
            }
        }});
    }
    
    // normalize the data based on the schema
    this.addRows = function(_d) {
        var rs = self.grid.getRecordSet();
        var nd = [];
        for (var i=0; i < _d.length; i++) {
            var row = {};
            for (var ii=0; ii < _d[i].length; ii++) {
                // this code allows for matching to the columin id with row data
                if (_d[i][ii].id) {
                    row[schema[_d[i][ii].id]] = _d[i][ii].value;
                } else {
                    row[schema[ii]] = _d[i][ii];
                }
            }
            nd.push(row);
        }
        rs.addRecords(nd);
        self.grid.populateTable();
    }
    
    /**
     * Add a row to the grid
     */
    this.addRow = function(_d) {
        var a= [];
        a.push(_d);
        self.addRows(a);
    }
    
    /**
     *  Clear the grid
     */
    this.clear = function() {
        var rs = self.grid.getRecordSet();
        rs.reset();
        while (self.grid.getRow(0) != null) {
            self.grid.deleteRow(self.grid.getRow(0));
        }
        ///self.grid.refreshTable();
    }
    
    /**
     * initialize the grid
     */
    function init() {
        // create the columns and editors
        for (var i = 0 ; i < cold.length; i++){
            var col = {};
            
            if (cold[i].id) {
                schema.push(cold[i].title);
                schema[cold[i].id] = cold[i].title;
            }
            else schema.push(cold[i].title);
            // mix in everything but the renderer and editor
            for (var ii in cold[i]) {
                if (ii == 'editor') {
                    // create new editor with the mixins
                    col.editor = cold[i].editor;
                } else if (ii == 'renderer') {      
                    col.renderer = cold[i].renderer; 
                } else if (ii == 'title') {    
                    col.key = cold[i].title;
                } else {
                    col[ii] = cold[i][ii];
                }
            }
            if (!col.sortable) col.sortable = true;
            cols.push(col);
        }
        // this needs to be opitmized
        function getSchemaIndex(id) {
            for (var i=0; i < schema.length; i++) {
                if (schema[i] == id) return i;
            }
            return -1;
        }
        
        // normalize data for yahoo which wants key value pairs for every row item
        for (var i=0; i < data.length; i++) {
            var row = {};
            for (var ii=0; ii < data[i].length; ii++) {
                // this code allows for matching to the columin id with row data
                if (data[i][ii].id) {
                    row[schema[data[i][ii].id]] = data[i][ii].value;
                } else {
                    row[schema[ii]] = data[i][ii];
                }
            }
            nData.push(row);
        }
        
        var columns = new YAHOO.widget.ColumnSet(cols);
        
        var ds = new YAHOO.util.DataSource(nData);
        ds.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
        ds.responseSchema = {fields :schema};
        
        
        
        //create the grid
        self.grid = new YAHOO.widget.DataTable(uuid, columns, ds,{fixedWidth: false,rowSingleSelect:rowSingleSelect,caption:""});
        self.grid.subscribe("cellClickEvent",self.grid.onEventEditCell);
        self.grid.subscribe("cellMouseoverEvent",self.grid.onEventHighlightCell);
        self.grid.subscribe("cellMouseoutEvent",self.grid.onEventUnhighlightCell);
        self.grid.subscribe("cellClickEvent",self.grid.onEventSelectRow); 
        
        
        //cell edit default event handler
        self.onCellEdit = function(oArgs) {
            var cellId =  oArgs.target.id;
            var oldData = oArgs.oldData; 
            var newData = oArgs.newData;
            YAHOO.log("Cell '" + cellId + "' was updated from '" +  
            oldData + "' to '" + newData + "'");
            var v = {cellId:cellId,oldData:oldData,newData:newData};
            jmaki.publish(topic + "/onEdit", {id:uuid,value:v});
        }
        
        //grid default event handlers
        self.onSelectRow = function() {
            // Returns an array of TR elements that are selected 
            //(for current page only, if pagination is enabled)
            var rows = self.grid.getSelectedRows();
            var v = {rows:rows};
            jmaki.publish(topic + "/onSelect", {id:uuid,value:v});
        }
        self.grid.subscribe("cellClickEvent",self.onSelectRow); 
        self.grid.subscribe("cellEditEvent",self.onCellEdit);
        
        //select the first row by default
        self.grid.select(self.grid.getRow(0)); 
        self.grid.populateTable();
    }
}